# coding:utf8

from appserver import db_store
from sqlalchemy import or_

from appserver import execute_sql
from appserver import sql_row_to_dict

from flask import session
from models.entity.tree_model_base import TreeModelBase

"""
模块数据模型
"""


class Module(TreeModelBase):
    __tablename__ = "modules"
    __bind_key__ = "main"

    # autoincrement=True,
    id = db_store.Column(db_store.Integer, primary_key=True, comment=u'模块编号')
    name = db_store.Column(db_store.String(64), nullable=False, comment=u'模块名称')
    code = db_store.Column(db_store.String(32), nullable=False, unique=True, comment=u"模块编码")
    description = db_store.Column(db_store.String(255), nullable=False, comment=u"描述")
    parent_id = db_store.Column(db_store.Integer, nullable=False, comment=u"父ID",default =0)
    path = db_store.Column(db_store.String(255), nullable=False, comment=u"路径")
    depth = db_store.Column(db_store.Integer, comment=u"深度",default=0)
    child_num = db_store.Column(db_store.Integer, comment=u"子类数量",default=0)
    dis_order = db_store.Column(db_store.Integer, comment=u"排序")
    target = db_store.Column(db_store.String(20), comment=u"目标")
    url = db_store.Column(db_store.String(255), default="", comment=u"地址")
    icon = db_store.Column(db_store.String(32), comment=u"图标")
    is_menu = db_store.Column(db_store.Integer, comment=u"是否为菜单") # 1-是菜单 0-不是菜单
    is_public = db_store.Column(db_store.Integer, comment=u"是否为公共")
    is_expand = db_store.Column(db_store.Integer, comment=u"是否展开")
    status = db_store.Column(db_store.Integer, comment=u"状态")  # 0-正常 1-禁用

    def __repr__(self):
        return "<Module %s>" % self.name

    @staticmethod
    def get_modules_by_depth(depth):
        return Module.query.filter_by(depth=depth).all()

    @staticmethod
    def get_module_by_code(code):
        return Module.query.filter_by(code=code).first()

    @staticmethod
    def get_modules_by_token(the_token):
        # button_list=Button.get_buttons_by_token(the_token)
        # module_set=set()
        # for item in button_list:
        #     module_set.add(Module.get_module_by_id(item.module_id))
        sql="select distinct path from modules where (id in (select distinct module_id from buttons where id in " \
            "(select button_id from tokens_with_buttons where token_id in (select id from tokens where tokens.token=\"%s\")))) and (status=0);" %(the_token.token)
        result=execute_sql(sql)
        mlist=set()
        for row in result:
            for module_id in [int(m_id) for m_id in sql_row_to_dict(row)["path"].split(",")]:
                mlist.add(module_id)
        return mlist

    @staticmethod
    def get_module_all_by_token(the_token):
        mlist=Module.get_modules_by_token(the_token)
        all_nodes=set()
        for item in mlist:
            all_nodes.add(Module.get_module_by_id(item))
        return list(all_nodes)


    @staticmethod
    def get_module_tree_by_token(the_token):
        modules=Module.get_modules_by_token(the_token)
        branches=[]
        for item in modules:
            branch_path_list=item.path.split(",")
            branch_module_list=[]
            for t_id in branch_path_list:
                branch_module_list.append(Module.get_module_by_id(t_id))
            branches.append(Module.get_module_tree_in_range(item,branch_module_list)[0])
        return branches

    @staticmethod
    def search(query_word):
        search_list=Module.query.filter(or_(Module.name.like("%"+query_word+"%"),Module.code.like("%"+query_word+"%"),
                                                                    Module.description.like("%"+query_word+"%"),Module.target.like("%"+query_word+"%"),
                                                                    Module.url.like("%"+query_word+"%"),Module.status.like("%"+query_word+"%"))).all()
        tlist=[]
        for item in search_list:
            # if item.id not in [p["id"] for p in session["auth"]["module_list"]]:
            #     continue
            tlist.append(item.to_dict())
        rdic={
                        "success":1,
                        "error_code":None,
                        "error_msg":None,
                        "data":tlist
                }
        return rdic
